home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / System Pulse ƒ / Source Code / Source / MenuBarEffects.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  6.2 KB  |  254 lines

  1. #include <Multiprocessing.h>
  2.  
  3. #include "MenubarEffects.h"
  4.  
  5. typedef struct 
  6. {
  7.     Byte x, r, g, b;
  8. }xrgb;
  9.  
  10.  
  11. xrgb     *gSavedMenuBar = nil;
  12. xrgb     *gRenderedPulse = nil;
  13. xrgb     *gRenderedDeadPulse = nil;
  14. xrgb     *gScreenMemoryBase = nil;
  15. short     gWidth;
  16. short     gHeight;
  17. long     gScreenRowBytes = 0;
  18. long    gScreenWidth = 0;
  19. MPQueueID     gQueue = 0;
  20. MPTaskID     gTask = 0;
  21.  
  22. xrgb     gSavedBGColor;
  23.  
  24. Rect     gPulseRect;
  25.  
  26. #define compare_xrgb(x1, x2) ((x1->r == x2->r) && (x1->g == x2->g) && (x1->b == x2->b))
  27.  
  28. ////////////////////////////////////////////////////////////////////////
  29.  
  30. void RenderPulse();
  31. void SavePosition(int hOffset);
  32. void StartMenuBarEffect();
  33. void MergePulseIntoMenuBar(int hOffset, xrgb* thePulse);
  34. void RestoreWreckedMenuBar(int hOffset, xrgb* thePulse);
  35. OSStatus EffectThreadProc(void *);
  36. void EndMenuBarEffect();
  37.  
  38. extern long MPSetTaskWeight(MPTaskID, long);
  39.  
  40. ////////////////////////////////////////////////////////////////////////
  41.  
  42.  
  43. ////////////////////////////////////////////////////////////////////////
  44.  
  45. OSStatus EffectThreadProc(void *)
  46. {
  47.     Duration wait = 100;
  48.     int maxStep = gWidth / 2;
  49.     while(1)
  50.     {
  51.         int position = 0;
  52.         int step = jGNECount();
  53.         if (step > maxStep) step = maxStep;
  54.         for (position = 0; position < gScreenWidth - gWidth; position += step + 1)
  55.         {
  56.             OSStatus stat;
  57.             xrgb *thePulse = (step == 0) ? gRenderedDeadPulse : gRenderedPulse;
  58.             SavePosition(position);
  59.             MergePulseIntoMenuBar(position, thePulse);
  60.             stat = MPWaitOnQueue(gQueue, nil, nil, nil,  wait);
  61.             RestoreWreckedMenuBar(position, thePulse);
  62.             step = jGNECount();
  63.             if (step > maxStep) step = maxStep;
  64.         }
  65.     }
  66.     
  67.     return noErr;
  68. }
  69.  
  70. ////////////////////////////////////////////////////////////////////////
  71.  
  72. void EndMenuBarEffect()
  73. {
  74.     MPTerminateTask(gTask, 0);
  75.     MPDeleteQueue(gQueue);
  76.     DisposePtr((Ptr)gSavedMenuBar);
  77.     DisposePtr((Ptr)gRenderedPulse);
  78.     DisposePtr((Ptr)gRenderedDeadPulse);
  79.     RemovejGNE();
  80. }
  81.  
  82. ////////////////////////////////////////////////////////////////////////
  83.  
  84. void StartMenuBarEffect()
  85. {
  86.     PixMapHandle     offscreenPixMap = nil;
  87.     CGrafPtr        grafPtr = nil;
  88.  
  89.     // Get a hold of the screen memory
  90.     // Get the row bytes
  91.     GetCWMgrPort(&grafPtr);
  92.     offscreenPixMap = GetGWorldPixMap(grafPtr);
  93.     gScreenRowBytes = GetPixRowBytes(offscreenPixMap);
  94.     gScreenMemoryBase = (xrgb*) (GetPixBaseAddr(offscreenPixMap) + gPulseRect.top * gScreenRowBytes);
  95.     
  96.     gPulseRect.top = 0;
  97.     gPulseRect.left = 0;
  98.     gPulseRect.bottom = gPulseRect.top + 18;
  99.     gPulseRect.right = 32;
  100.     
  101.     gWidth = gPulseRect.right - gPulseRect.left;
  102.     gHeight = gPulseRect.bottom - gPulseRect.top;
  103.     
  104.     gScreenWidth = (grafPtr->portRect.right - grafPtr->portRect.left);
  105.  
  106.     // Determine the background color
  107.     // very cheesey, assume the fourth pixel has the bg color.
  108.     gSavedBGColor = * (((xrgb*) (gScreenMemoryBase + 3 *gScreenRowBytes) ) + 4);
  109.     
  110.     // allocate a buffer to save the rendered pulse to.
  111.     gRenderedPulse = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
  112.     
  113.     // allocate a buffer to save the rendered pulse to.
  114.     gRenderedDeadPulse = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
  115.     
  116.     // Render a pulse, since they are all the same.
  117.     
  118.     RenderPulse();
  119.     
  120.     // allocate a buffer to save the affected menubar area to.
  121.     gSavedMenuBar = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
  122.     
  123.     InstalljGNE();
  124.     
  125.     // Create a queue 
  126.     {
  127.     OSStatus stat1 = MPCreateQueue(&gQueue);
  128.     OSStatus stat2 = MPCreateTask(EffectThreadProc, nil,0,0,nil,nil,0, &gTask);
  129.     stat1 = MPSetTaskWeight(gTask, 250);
  130.     }
  131. }
  132.  
  133. ////////////////////////////////////////////////////////////////////////
  134. // Save a portion of the menu bar 
  135.  
  136. void SavePosition(int hOffset)
  137. {
  138.     Ptr srcPtr = (Ptr) (gScreenMemoryBase + hOffset);
  139.     Ptr destPtr = (Ptr) gSavedMenuBar;
  140.     int i;
  141.  
  142.     for (i = 0; i < gHeight; i++, srcPtr += gScreenRowBytes, destPtr += gWidth * sizeof(xrgb))
  143.     {
  144.         BlockMoveData(srcPtr, destPtr, gWidth * sizeof(xrgb));
  145.     }
  146. }
  147.  
  148. ////////////////////////////////////////////////////////////////////////
  149. // Render the pulse once and reuse it.
  150.  
  151. void RenderPulse()
  152. {
  153.     xrgb*     line1 = gRenderedDeadPulse;
  154.     xrgb*     p = gRenderedDeadPulse;
  155.     int     i = 0;
  156.     xrgb*     p2;
  157.     int        detent = (1000 * (255 -  gSavedBGColor.r)) / gWidth;
  158.     // Render the first line
  159.     for (i = 0; i < gWidth; i++, p++)
  160.     {
  161.         p->x = 0;
  162.         p->r = gSavedBGColor.r + (detent * i)/ 1000;
  163.         p->g = gSavedBGColor.g - i*8;
  164.         p->b = gSavedBGColor.b - i*8;
  165.     }
  166.     
  167.     // Copy the first line to the rest
  168.     for (i = 1, p2 =  gRenderedDeadPulse + gWidth; i < gHeight; i++, p2 += gWidth)
  169.     {
  170.         BlockMoveData(line1, (Ptr)p2, gWidth * sizeof(xrgb));
  171.     }
  172.     
  173.     p = line1 = gRenderedPulse;
  174.     detent = (1000 * (255 -  gSavedBGColor.g)) / gWidth;
  175.     // Render the first line
  176.     for (i = 0; i < gWidth; i++, p++)
  177.     {
  178.         p->x = gSavedBGColor.x;
  179.         p->g = gSavedBGColor.g + (detent * i)/ 1000;
  180.         
  181.         p->r = gSavedBGColor.r - i*8;
  182.         p->b = gSavedBGColor.b - i*8;
  183.     }
  184.     
  185.     // Copy the first line to the rest
  186.     for (i = 1, p2 =  gRenderedPulse + gWidth; i < gHeight; i++, p2 += gWidth)
  187.     {
  188.         BlockMoveData(line1, (Ptr)p2, gWidth * sizeof(xrgb));
  189.     }
  190. }
  191.  
  192. ////////////////////////////////////////////////////////////////////////
  193.  
  194. void MergePulseIntoMenuBar(int hOffset, xrgb* thePulse)
  195. {
  196.     Ptr destPtr = (Ptr) (gScreenMemoryBase + hOffset);
  197.     Ptr srcPtr = (Ptr) thePulse;
  198.     int stride = gWidth * sizeof(xrgb);
  199.     int row, col;
  200.  
  201.     for (row = 0; row < gHeight; row++, destPtr += gScreenRowBytes, srcPtr += stride)
  202.     {
  203.         xrgb *s = (xrgb*) srcPtr;
  204.         xrgb *p = (xrgb*) destPtr;
  205.         
  206.         for (col = 0; col < gWidth; col++)
  207.         {
  208.             if (compare_xrgb((&gSavedBGColor), p))
  209.             {
  210.                 *p = *s;
  211.             }
  212.             p++;
  213.             s++;
  214.         }
  215.     }
  216. }
  217.  
  218. ////////////////////////////////////////////////////////////////////////
  219.  
  220. void RestoreWreckedMenuBar(int hOffset, xrgb* thePulse)
  221. {
  222.     Ptr destPtr = (Ptr) (gScreenMemoryBase + hOffset);
  223.     Ptr srcPtr = (Ptr) gSavedMenuBar;
  224.     Ptr cmpPtr = (Ptr) thePulse;
  225.     int row, col;
  226.     int stride = gWidth * sizeof(xrgb);
  227.  
  228.     for (row = 0; 
  229.         row < gHeight; 
  230.         row++, destPtr += gScreenRowBytes, srcPtr += stride, cmpPtr += stride)
  231.     {
  232.         xrgb *s = (xrgb*) srcPtr;
  233.         xrgb *p = (xrgb*) destPtr;
  234.         xrgb *c = (xrgb*) cmpPtr;
  235.         
  236.         for (col = 0; col < gWidth; col++, c++, p++, s++)
  237.         {
  238.             // if the color is from the rendered data, copy the saved color back
  239.             if (compare_xrgb(c, p))
  240.             {
  241.                 *p = *s;
  242.             }
  243.             // if the color is not what we saved, then the menubar needs to be
  244.             // refreshed.
  245.             else if (!compare_xrgb(s, p))
  246.             {
  247.                 doRefreshMenuBar();
  248.             }
  249.         }
  250.     }
  251.     
  252. }
  253.  
  254.